package com.grantheath.erebus.model 
{
	import com.grantheath.erebus.model.enum.notifications.ErebusInitializationNotifications;
	import com.grantheath.erebus.model.enum.names.ErebusProxyNames;
	import com.grantheath.erebus.model.interfaces.IErebusSiteTreeProxy;
	import com.grantheath.erebus.model.interfaces.IErebusAssetNode;
	import com.grantheath.erebus.model.interfaces.IErebusPageNode;

	import org.puremvc.as3.patterns.proxy.Proxy;

	/**
	 * @author grantheath
	 */
	public class ErebusSiteTreeProxy extends Proxy implements IErebusSiteTreeProxy 
	{
		//PRIVATE VARIABLES
		private var _siteTree : IErebusPageNode;
		private var _isTransitioning : Boolean;
		private var _interruptTransition : Boolean;
		private var _uninitializeQueue : Array;
		private var _loadQueue : Array;
		private var _displayQueue : Array;
		private var _hideQueue : Array;
		private var _assetQueue : Array;
		private var _loadedPages : Array;
		private var _displayedPages : Array;
		private var _initialized : Boolean;

		public function ErebusSiteTreeProxy()
		{
			super(ErebusProxyNames.SITE_TREE_PROXY);
			//initialize variables
			_displayedPages = new Array();
			_loadedPages = new Array();
			_uninitializeQueue = new Array();
			_loadQueue = new Array();
			_displayQueue = new Array();
			_hideQueue = new Array();
			_assetQueue = new Array();
			_isTransitioning = false;
			_interruptTransition = false;
		}

		public function getPageNodeFromURL(URL : String) : IErebusPageNode
		{
			var URLArray : Array;
			var returnNode : IErebusPageNode;
			
			URLArray = URL.split("?");
			URLArray = String(URLArray[0]).split("/").filter(filterNullArrayValues);
			returnNode = getPageNodeFromURLArray(URLArray);
			
			return returnNode;
		}

		public function getPageNodeFromURLArray(URLArray : Array) : IErebusPageNode
		{
			var samplePageNodes : Array = _siteTree.children;
			var returnNode : IErebusPageNode;
			
			if(URLArray.length > 0) {
				while(URLArray.length > 0) {
					var success : Boolean = false;
					
					for each(var samplePageNode : IErebusPageNode in samplePageNodes) {
						if(samplePageNode.pageId == (URLArray[0]) as String) {
							returnNode = samplePageNode;
							samplePageNodes = samplePageNode.children;
							URLArray = URLArray.slice(1);
							success = true;
						}
					}
					if(!success) {
						break;
					}
				}
			}
			if(returnNode) {
				return returnNode;
			} else {
				return null;
			}
		}

		//and array filter function
		//used to filter out null array values after the split function is used
		public function filterNullArrayValues(element : String, index : uint, arr : Array) : Boolean
		{
			index;
			arr;
			if(element == "") {
				return false;
			} else {
				return true;
			}
		}

		//function for incrementing the site tree queues
		public function incrementDisplayQueue() : IErebusPageNode
		{
			displayQueue = displayQueue.slice(1);
			return displayQueue[0] as IErebusPageNode;
		}

		public function incrementLoadQueue() : IErebusPageNode
		{
			loadQueue = loadQueue.slice(1);
			return loadQueue[0] as IErebusPageNode;
		}

		public function incrementHideQueue() : IErebusPageNode
		{
			hideQueue = hideQueue.slice(1);
			return hideQueue[0] as IErebusPageNode;
		}

		public function incrementUninitializeQueue() : IErebusPageNode
		{
			uninitializeQueue = uninitializeQueue.slice(1);
			return uninitializeQueue[0] as IErebusPageNode;
		}

		public function incrementAssetQueue() : IErebusAssetNode
		{
			assetQueue = assetQueue.slice(1);
			return assetQueue[0] as IErebusAssetNode;
		}

		//functions for registering and unregistering displayed and loaded pages
		public function registerLoadedPageNode(loadedPageNode : IErebusPageNode) : void
		{
			loadedPages.push(loadedPageNode);
		}

		public function registerDisplayedPageNode(displayedPageNode : IErebusPageNode) : void
		{
			displayedPages.push(displayedPageNode);
		}

		public function unregisterLoadedPageNode(loadedPageNode : IErebusPageNode) : void
		{
			var newLoadedPageArray : Array = new Array();
			
			if(loadedPageNode.page) {
				loadedPageNode.page.uninitializePage();
			}
			loadedPageNode.page = null;
			for each(var assetNode : IErebusAssetNode in loadedPageNode.pageAssets) {
				assetNode.asset = null;
			}
			for each(var pageNode : IErebusPageNode in loadedPages) {
				if(loadedPageNode != pageNode) {
					newLoadedPageArray.push(pageNode);
				}
			}
			loadedPages = newLoadedPageArray;
		}

		public function unregisterDisplayedPageNode(displayedPageNode : IErebusPageNode) : void
		{
			var newDisplayedPageArray : Array = new Array();
			
			for each(var pageNode : IErebusPageNode in displayedPages) {
				if(displayedPageNode != pageNode) {
					newDisplayedPageArray.push(pageNode);
				}
			}
			displayedPages = newDisplayedPageArray;
		}

		//functions for checking to see if a page is loaded or displayed
		public function isLoaded(pageNode : IErebusPageNode) : Boolean
		{
			if(loadedPages.indexOf(pageNode) == -1) {
				return false;
			}
			return true;
		}

		public function isDisplayed(pageNode : IErebusPageNode) : Boolean
		{
			if(displayedPages.indexOf(pageNode) == -1) {
				return false;
			}
			return true;
		}

		//GETTERS AND SETTERS
		public function get tree() : IErebusPageNode
		{
			return _siteTree;
		}

		public function set tree(tree : IErebusPageNode) : void
		{
			_siteTree = tree;
			_initialized = true;
			sendNotification(ErebusInitializationNotifications.INITIALIZE_PROXIES);
		}

		public function get loadQueue() : Array
		{
			return _loadQueue;
		}

		public function set loadQueue(loadQueue : Array) : void
		{
			_loadQueue = loadQueue;
		}

		public function get displayQueue() : Array
		{
			return _displayQueue;
		}

		public function set displayQueue(displayQueue : Array) : void
		{
			_displayQueue = displayQueue;
		}

		public function get assetQueue() : Array
		{
			return _assetQueue;
		}

		public function set assetQueue(assetQueue : Array) : void
		{
			_assetQueue = assetQueue;
		}

		public function get isTransitioning() : Boolean
		{
			return _isTransitioning;
		}

		public function set isTransitioning(isTransitioning : Boolean) : void
		{
			_isTransitioning = isTransitioning;
		}

		public function get interuptTransition() : Boolean
		{
			return _interruptTransition;
		}

		public function set interuptTransition(interuptTransition : Boolean) : void
		{
			_interruptTransition = interuptTransition;
		}

		public function get loadedPages() : Array
		{
			return _loadedPages;
		}

		public function set loadedPages(loadedPages : Array) : void
		{
			_loadedPages = loadedPages;
		}

		public function get displayedPages() : Array
		{
			return _displayedPages;
		}

		public function set displayedPages(displayedPages : Array) : void
		{
			_displayedPages = displayedPages;
		}

		public function get hideQueue() : Array
		{
			return _hideQueue;
		}

		public function set hideQueue(hideQueue : Array) : void
		{
			_hideQueue = hideQueue;
		}

		public function get uninitializeQueue() : Array
		{
			return _uninitializeQueue;
		}

		public function set uninitializeQueue(uninitializeQueue : Array) : void
		{
			_uninitializeQueue = uninitializeQueue;
		}

		public function get lastDisplayed() : IErebusPageNode
		{
			if(displayedPages.length > 0) {
				return displayedPages[displayedPages.length - 1] as IErebusPageNode;
			}
			return null;
		}
		
		public function get initialized() : Boolean
		{
			return _initialized;
		}
	}
}
